using System;
using System.Collections;
using Cinemachine;
using LogSystem;
using UnityEngine;
using Yoozoo.HRP.Runtime;
using Yoozoo.Mars.Got;

namespace Yoozoo.Gameplay.Liberty.PlayerController
{
    public class PlayerCameraController : MonoBehaviour
    {
        public InputCameraConfig inputCameraConfig;
        
        public HCamera hCamera;
        public Camera playerCamera;
        public CinemachineBrain cameraBrain;

        public PlayerSyncCamera syncCameraComponent;
        
        public CinemachineVirtualCamera inputVirtualCamera;
        public CinemachineVirtualCamera hangingVirtualCamera;
        public CinemachineVirtualCamera lookAtVirtualCamera;
        public CinemachineVirtualCamera lookAtVirtualCamera2;
        public CinemachineVirtualCamera syncVirtualCamera;

        public BehaviorCameraCollection behaviorCameraCollection;

        public Transform defaultLookAt;

        private float _defaultLookAtFov = 60;
        
        private CinemachineVirtualCamera _currentVirtualCamera;


        public Transform viewerRoot;

        public SceneTransformDetector sceneDetector;
        public SceneTransformDetector npcDetector;
        public SceneTransformDetector carBirthPointDetector;
        
        private void Awake()
        {
            _defaultLookAtFov = lookAtVirtualCamera.m_Lens.FieldOfView;
        }

        public void ChangeCameraBlend(CinemachineBlendDefinition.Style style, float time)
        {
            cameraBrain.m_DefaultBlend = new CinemachineBlendDefinition(style, time);
        }

        public void Change2ImmediatelyBlend()
        {
            ChangeCameraBlend(CinemachineBlendDefinition.Style.Cut,0);
        }

        public void SetSyncCamera(Camera cam)
        {
            syncCameraComponent.syncCamera = cam;
        }

        public void SwitchSync(bool enable)
        {
            behaviorCameraCollection.SwitchSync(enable);
        }
        
        public void Switch2InputCamera()
        {
            if ( _currentVirtualCamera == inputVirtualCamera)
            {
                return;
            }
            
            if (_currentVirtualCamera)
            {
                _currentVirtualCamera.m_Priority = 0;
            }
            inputVirtualCamera.m_Priority = 100;
            _currentVirtualCamera = inputVirtualCamera;
        }

        public void Switch2HangingCamera()
        {
            if (_currentVirtualCamera)
            {
                _currentVirtualCamera.m_Priority = 0;
            }

            if (viewerRoot)
            {
                hangingVirtualCamera.m_Follow = viewerRoot;
                hangingVirtualCamera.m_LookAt = viewerRoot;
            }
            //hangingVirtualCamera.enabled = true;
            hangingVirtualCamera.m_Priority = 100;
            _currentVirtualCamera = hangingVirtualCamera;
        }

        public void EnterStreetScene(CinemachineBlendDefinition.Style blendType, float blendTime)
        {
            ChangeCameraBlend(blendType, blendTime);
            Switch2InputCamera();
        }

        public void Switch2LookAtCamera(Vector3 position,Vector3 eulerAngles,float fov = 0)
        {
            if (_currentVirtualCamera)
            {
                _currentVirtualCamera.m_Priority = 0;
            }

            CinemachineVirtualCamera vc = null;
            if (_currentVirtualCamera == lookAtVirtualCamera)
            {
                vc = lookAtVirtualCamera2;
            }
            else if (_currentVirtualCamera == lookAtVirtualCamera2)
            {
                vc = lookAtVirtualCamera;
            }
            else
            {
                vc = lookAtVirtualCamera;
            }

            if (vc)
            {
                vc.m_Priority = 100;
                vc.transform.position = position;
                vc.transform.eulerAngles = eulerAngles;
                _currentVirtualCamera = vc;
            }

            if (fov > 0)
            {
                lookAtVirtualCamera.m_Lens.FieldOfView = fov;
                lookAtVirtualCamera2.m_Lens.FieldOfView = fov;
            }
            else
            {
                lookAtVirtualCamera.m_Lens.FieldOfView = inputVirtualCamera.m_Lens.FieldOfView;
                lookAtVirtualCamera2.m_Lens.FieldOfView = inputVirtualCamera.m_Lens.FieldOfView;
            }
            
        }

        public void Switch2SyncCamera()
        {
            if (_currentVirtualCamera)
            {
                _currentVirtualCamera.m_Priority = 0;
            }
            syncVirtualCamera.m_Priority = 100;
            _currentVirtualCamera = syncVirtualCamera;
        }

        public void SyncCurrentVirtualCamera()
        {
            if (_currentVirtualCamera)
            {
                playerCamera.transform.position = _currentVirtualCamera.transform.position;
                playerCamera.transform.rotation = _currentVirtualCamera.transform.rotation;

                playerCamera.fieldOfView = _currentVirtualCamera.m_Lens.FieldOfView;
                playerCamera.nearClipPlane = _currentVirtualCamera.m_Lens.NearClipPlane;
                playerCamera.farClipPlane = _currentVirtualCamera.m_Lens.FarClipPlane;
            }
        }
        
        public void SetCameraLookAtPos(Vector3 lookAtPos)
        {
            lookAtVirtualCamera.m_LookAt = defaultLookAt;
            lookAtVirtualCamera2.m_LookAt = defaultLookAt;
            defaultLookAt.position = lookAtPos;
        }
        
        public void SetCameraLookAtTransform(Transform lookAt)
        {
            lookAtVirtualCamera.m_LookAt = lookAt;
            lookAtVirtualCamera2.m_LookAt = lookAt;
        }

   
        public void Switch2BehaviorCamera(string cameraName, Action<BehaviorCamera> callBack = null)
        {
            if (behaviorCameraCollection)
            {
                var bCamera = behaviorCameraCollection.GetBehaviorCamera(cameraName);
                if (bCamera!=null)
                {
                    if (Application.isPlaying)
                    {
                        Timers.inst.StartCoroutine(SwitchBCamera(bCamera,callBack));
                    }
                    else
                    {
                        SwitchBehaviorCamera2(bCamera, callBack);
                        bCamera.virtualCamera.m_Priority = 80;
                    }
                }
                else
                {
                    Debug.LogError(LogModule.LibertyScene, "找不到行为相机：" + cameraName);
                }
            }
        }

        public void SetCameraOcclusionCullingActive(bool active)
        {
            if (playerCamera!=null)
            {
                playerCamera.useOcclusionCulling = active;
            }
        }
        private IEnumerator SwitchBCamera(BehaviorCamera bCamera, Action<BehaviorCamera> callBack)
        {
            yield return new WaitForEndOfFrame();
            yield return new WaitForEndOfFrame();
            SwitchBehaviorCamera2(bCamera, callBack);
        }


        private void SwitchBehaviorCamera2(BehaviorCamera bCamera, Action<BehaviorCamera> callBack)
        {
            if (_currentVirtualCamera)
            {
                _currentVirtualCamera.m_Priority = 0;
            }
            bCamera.virtualCamera.m_Priority = 100;
            
            if (viewerRoot && hangingVirtualCamera && hangingVirtualCamera == bCamera.virtualCamera)
            {
                // 推图相机
                hangingVirtualCamera.m_Follow = viewerRoot;
                hangingVirtualCamera.m_LookAt = viewerRoot;
            }
            
            _currentVirtualCamera = bCamera.virtualCamera;
            callBack?.Invoke(bCamera);
        }
        
    }
}